import { loginApi, getUserInfoApi, logoutApi } from './../api/acl/login';
import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import type { UserInfoState } from './interface';
import {ElMessage} from 'element-plus'
import {staticRoutes, allAsyncRoutes, anyRoute} from '@/router/routes'
import type { RouteRecordRaw } from 'vue-router';
import { useRouter } from 'vue-router';
const router = useRouter();

type userInfoData = {
  userInfo: UserInfoState
}

/**
 * 拿到用户路由，根据路由信息来获取动态路由
 */
function getUserinfoAsyncRoutes(userAsyncRoutes:string[], allAsyncRoutes: RouteRecordRaw[]) { 
  // userAsyncRoutes：用户携带的路由信息,其中存储的是路由的name,首字母大写
  // allAsyncRoutes：所有动态路由信息
  // 1. 定义数组接受最终结果
  let result:RouteRecordRaw[] = [];
  // 2. 遍历所有动态路由，根据用户返回的路由信息来确定所有动态路由中的路由去留
  allAsyncRoutes.forEach(item => {
    if (userAsyncRoutes.includes(item.name as string)) { // 存在路由，并且有子路由
      // 添加路由
      result.push(item);
      if(item.children){ // 有子元素
        getUserinfoAsyncRoutes(userAsyncRoutes, item.children);
      }
    }
  })
  return result;
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore('userInfo', {

	state: ():userInfoData => {
    return {
      userInfo:{  // 这里的userInfo是个对象里面的属性(只不过这个属性的值是个变量)，所以不能直接对其进行约束
        token: getToken() || '',  // 自动登录
        avatar: '',
        name: '',
        buttons: [],
        roles: [],     // 角色
        // routes: [],    // 路由
        menuRoutes: []
      }
    }
  },

	actions: {
    // 1. 登录
    async login (username: string, password: string) {
      // 发送请求获取登录数据
      let loginRes = await loginApi(username, password);
      console.log('loginres',loginRes)
      // 将数据存储到本地和pinia中
      setToken(loginRes.token);
      this.userInfo.token = loginRes.token;

      return 'ok';
      // return new Promise((resolve, reject) => {
      //   setTimeout(() => {
      //     if (username==='admin' && password==='111111') {
      //       const token = 'token-atguigu'
      //       setToken(token)
      //       this.token = token
      //       resolve(token)
      //     } else {
      //       reject(new Error('用户名或密码错误!'))
      //       ElMessage.error('用户名或密码错误!')
      //     }
      //   }, 1000)
      // })
    },

    // 2. 获取用户信息
    async getInfo () {
      // 2.1 获取结果
      let result = await getUserInfoApi();
      // console.log('----------',result)
      // 将用户信息渲染到页面
      this.userInfo.name = result.name;
      this.userInfo.avatar = result.avatar;
      this.userInfo.buttons = result.buttons;
      this.userInfo.roles = result.roles;
      // 路由(静态)
      // this.userInfo.menuRoutes = staticRoutes;
      // 获取路由,将404(anyRoute)页面放到最后
      Object.assign(this.userInfo.menuRoutes, staticRoutes, getUserinfoAsyncRoutes(result.routes, allAsyncRoutes), anyRoute);
      console.log('this.userInfo.menuRoutes',this.userInfo.menuRoutes)
      // 注册所有获取到的路由
      this.userInfo.menuRoutes.forEach(item => {
        router.addRoute(item);  // 使用vue-router中的addRoute()单个注册路由
      });
      // this.userInfo.menuRoutes = staticRoutes;
      // this.userInfo.routes = result.routes;
      return 'ok'
    },

    // 3. 退出登录
    async logOut() {
      // 3.2 发送请求退出登录
      let outRes = await logoutApi();
      console.log('退出登录',outRes);
      // 3.1 先清除前台数据
      this.reset();
      return 'ok'
    },

    // 重置浏览器中的用户信息
    reset () {
      // 删除local中保存的token
      removeToken()
      // 提交重置用户信息
      this.userInfo = {
        token: getToken() || '',  // 此处必须手动重置token，否则退出登录后路由不跳转
        avatar: '',
        name: '',
        buttons: [],
        roles: [],     // 角色
        // routes: [],    // 路由
        menuRoutes: []
      }
    },
	},
});
